package com.changgou.system.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.changgou.system.entity.Page;
import com.changgou.system.search.pojo.SkuInfo;
import com.changgou.system.search.service.SearchService;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.util.concurrent.ConcurrentHashMapLong;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;
   // private HighlightBuilder highlightBuilder;



    @Override
    public Map search(Map<String, String> searchMap) {
        Map<String, Object> resultMap = new HashMap<>();
        //有条件才查询Es
        if (!(searchMap == null)) {
            NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
            // MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
          //  0:关键词
            if (!StringUtils.isEmpty(searchMap.get("keyword"))) {
                MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", searchMap.get("keyword")).operator(Operator.AND);
                boolQueryBuilder.must(matchQueryBuilder);
            }
            //1:条件 品牌
            if(!StringUtils.isEmpty(searchMap.get("brand"))){
              //term 查询
                TermQueryBuilder queryBuilder = QueryBuilders.termQuery("brandName", searchMap.get("brand"));
                boolQueryBuilder.filter(queryBuilder);
            }
            //规格查询
            Set<String> keySet = searchMap.keySet();
            for (String key : keySet) {
                //规格参数
                if(key.startsWith("spec_")){
                    String value = searchMap.get(key);
                    value.replace("%2B","+");
                    TermQueryBuilder queryBuilder = QueryBuilders.termQuery("specMap." + key.substring(5) + ".keyword", value);
                    boolQueryBuilder.filter(queryBuilder);
                }

            }

            //按照价格
               if(StringUtils.isNotEmpty(searchMap.get("price"))) {
                   String[] prices = searchMap.get("price").split("-");
                   //price=500-1000
                   RangeQueryBuilder rangeQueryBuilder=QueryBuilders.rangeQuery("price").gte(prices[0]);
                   if (prices.length == 2) {
                       rangeQueryBuilder = rangeQueryBuilder.lte(prices[1]);

                       // boolQueryBuilder.filter(rangeQueryBuilder);
                   }
                       //price=3000
                     //  rangeQueryBuilder = QueryBuilders.rangeQuery("price").gte(prices[0]);

                       // boolQueryBuilder.filter(rangeQueryBuilder);
                   boolQueryBuilder.filter(rangeQueryBuilder);


               }


            nativeSearchQueryBuilder.withQuery(boolQueryBuilder);

            //品牌聚合(分组)查询
            String skuBrand="skuBrand";
            TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms(skuBrand).field("brandName");
            nativeSearchQueryBuilder.addAggregation(aggregationBuilder);
           // 规格聚合查询
            String skuSpec="skuSpec";
            TermsAggregationBuilder aggregationBuilders = AggregationBuilders.terms(skuSpec).field("spec.keyword");
            nativeSearchQueryBuilder.addAggregation(aggregationBuilders);

            //分页
            String pageNum = searchMap.get("pageNum");
            String pageSize = searchMap.get("pageSize");
            if(StringUtils.isEmpty(searchMap.get("pageNum"))){
                pageNum="1";

            }
            if(StringUtils.isEmpty(searchMap.get("pageSize"))){
                pageSize="30";
            }
            nativeSearchQueryBuilder.withPageable(PageRequest.of(Integer.parseInt(pageNum)-1,Integer.parseInt(pageSize)));
            //排序
            if(StringUtils.isNotEmpty(searchMap.get("sortField"))&&StringUtils.isNotEmpty(searchMap.get("sortRule"))){
                if(searchMap.get("sortRule").equals("ASC")){
                    nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(searchMap.get("sortField")).order(SortOrder.ASC));

                }
                nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(searchMap.get("sortField")).order(SortOrder.DESC));
            }

            //高亮   name 字段
            //高亮字段
            //前缀
            //后缀
      //设置高亮域
            HighlightBuilder.Field field = new HighlightBuilder.Field("name");
//前缀
            field.preTags("<span style='color:red'>");
//后缀
            field.postTags("</span>");
            nativeSearchQueryBuilder.withHighlightFields(field);


            AggregatedPage<SkuInfo> skuInfos = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), SkuInfo.class, new SearchResultMapper() {
                @Override
                //获取结果
                //回调方法
                public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
                    // 查询结果操作
                    List<T> skuList = new ArrayList<>();
                    // 获取结果
                    SearchHits hits = searchResponse.getHits();
                    for (SearchHit hit : hits) {
                        SkuInfo skuInfo = new SkuInfo();
                        //获取json字符串格式的数据
                        //{name:zhangsan,age:12} jsonString
                        //元字符串
                        String sourceAsString = hit.getSourceAsString();
                        SkuInfo skuInfo2 = JSON.parseObject(sourceAsString, SkuInfo.class);
                        Map<String, HighlightField> highlightFields=hit.getHighlightFields();
                        HighlightField highlightField = highlightFields.get("name");
                        Text[] fragments =highlightField.getFragments();
                         StringBuffer sb=new StringBuffer();
                        for (Text fragment : fragments) {
                            sb.append(fragment);
                        }
                        String hilightName = sb.toString();
                        skuInfo2.setName(hilightName);

                        skuList.add((T) skuInfo2);
                    }
                    //封装返回值  AggregatedPage
                    return new AggregatedPageImpl<>(skuList, pageable, hits.totalHits, searchResponse.getAggregations());
                }
            });
            //根据和前端的讨论结果定的
            //总记录数
            resultMap.put("total", skuInfos.getTotalElements());
            //总页数
            resultMap.put("totalPages", skuInfos.getTotalPages());
            // 查询结果集合
            resultMap.put("rows", skuInfos.getContent());


            //品牌聚合
          List<String> brandList=new ArrayList<>();
//           //拿到所有的聚合
            Aggregations aggregations = skuInfos.getAggregations();
            Map<String, Aggregation> asMap =aggregations.getAsMap();
           Terms aggregation = (Terms) asMap.get(skuBrand);
            List<? extends Terms.Bucket> buckets = aggregation.getBuckets();
            for (Terms.Bucket bucket : buckets) {
                String keyAsString = bucket.getKeyAsString();
              brandList.add(keyAsString);

            }
            resultMap.put("brandList",brandList);
           //所有聚合 拿出spec

//            List<String> specList=new ArrayList<>();
//            Terms specaggregation = (Terms) asMap.get(skuBrand);
//            List<? extends Terms.Bucket> specbuckets = aggregation.getBuckets();
//            for (Terms.Bucket bucket : specbuckets) {
//                String keyAsString = bucket.getKeyAsString();
//                specList.add(keyAsString);
//            }
//            resultMap.put("specList",this.formartSpec(specList));
//       //当前页
            //封装规格分组结果
            StringTerms specTerms = (StringTerms) skuInfos.getAggregation(skuSpec);
            List<String> specList = specTerms.getBuckets().stream().map(bucket -> bucket.getKeyAsString()).collect(Collectors.toList());
            resultMap.put("specList", this.formartSpec(specList));

           resultMap.put("pageNum",pageNum);

            return resultMap;
        }
        return null;
    }


//    public Map<String,Set<String>> formartSpec(List<String> specList) {
//        Map<String, Set<String>> resultMap = new HashMap<>();
//
//        for (String spec : specList) {
//
//         //   Map<String, String> map = JSON.parseObject(spec, Map.class);
//            Map<String, String> specMap=JSON.parseObject(spec,Map.class);
//            for (String key : specMap.keySet()) {
//                //key: 颜色 value : 蓝色
//
//                Set<String> specValue = resultMap.get(key);
//                if (specValue == null) {
//                    specValue = new HashSet<>();
//                }
//                specValue.add(specMap.get(key));
//                resultMap.put(key, specValue);
//            }
//
//        }
//        return resultMap;
//    }
public Map<String, Set<String>> formartSpec(List<String> specList) {
    //1定义返回map
    Map<String, Set<String>> resultMap = new HashMap<>();
    //2遍历specList
    if (specList != null && specList.size() > 0) {
        for (String specJsonString : specList) {
            // 将json转为map
            Map<String, String> specMap = JSON.parseObject(specJsonString, Map.class);
            //遍历每个商品的规格名字
            for (String specKey : specMap.keySet()) {
                //看返回map中有此规格没有
                Set<String> specSet = resultMap.get(specKey);
                if (specSet == null) {
                    specSet = new HashSet<>();
                }
                //将此条数据中的规格放入set
                specSet.add(specMap.get(specKey));
                //将set放入返回map
                resultMap.put(specKey, specSet);
            }
        }
    }
    return resultMap;

}
}
